#include <iostream>
#include "struttura_dati.h"
#include "manip_turno.h"
#include <stdlib.h>
#include <gtk/gtk.h>
#include <sstream>
#include <time.h> 

using namespace std;

extern partita_t partita;
extern turno_t turno;
extern GtkBuilder *builder;
extern gioca_t gioca;

/** Tipo enum che rappresenta i vari nomi che le carte possono assumere.
 *  Sono nomi caratteristici del gioco 'Briscola', e vengono utilizzati per 
 *  classificare le carte in base al valore di ogniuna, e in base alla briscola
 *  corrente.
 */
enum prior_carta_gioco {niente, liscio, punti, briscola_p, carico, briscola_a}; 	

/** Crea tre carte di tipo enum, che rappresentano le tre carte del computer.
 */
static prior_carta_gioco carta0, carta1, carta2;

/** Intero che mi indica l'indice della mano corrispondente alla carta che ho 
 *  scelto di giocare.
 */
static int scelta;

/** Funzione che prende l'indice della mano del pc, quindi la carta,
 *  e gli attribuisce una determinata priorità.
 *  Funzione usata sia quando il pc gioca per primo, che per secondo.
 *  idx --> indice della mano
 *  plr --> booleano che indica se si sta riferendo al giocatore, o al pc.
 */
static prior_carta_gioco prendi_carta(int idx, bool plr){	
	D1(cout<<"INIZIO DEBUG prendi_carta"<<endl);	
	// carta rappresenta il valore della carta giocata
	int carta;

	// si riferisce al player2, ovvero al computer.
	if(plr == false)
		carta = partita.player2.mano[idx].val;
	// si riferisce al player1, ovvero il giocatore.
	else
		carta = partita.player1.mano[idx].val;

	// recupera la briscola.
	int briscola = partita.mazzo[6].val;

	// se sono alla fine del gioco, e quindi non devo considerare questa carta.
  	if(carta==-1)
		return niente;
	
	// RECUPERATO TUTTE LE INFO, ADESSO TROVA LA PRIORITÀ...
	
	// quando è una briscola.
	if(carta/10 == briscola/10){
		/* valuta se la briscola è grande o piccola, utilizzando l'array PESI :
		   è piccola se PESI[carta%10] è minore di quella del rè(<=9) perchè
	      si considera che il rè, il tre e l'asso siano briscole alte.
       */
		D2(cout<<"verificato che è briscola"<<endl);
		if(PESI[carta%10] <= PESI[8])
			return briscola_p;
		else
			return briscola_a;
		}

	// quando è liscio. Sicuramente non è una briscola.
	if(PESI[carta%10] == 0){
		D2(cout<<"verificato che è liscio"<<endl);
		return liscio;
		}
	// quando è punti.
	if(PESI[carta%10] <= 4){
		D2(cout<<"verificato che è punti"<<endl);
		return punti;
		}
	// rimane solo carico. Avrebbe altrimenti incontrato già un return.
	D2(cout<<"verificato che è carico"<<endl);
	D1(cout<<"FINE DEBUG PRENDI CARTA"<<endl);	
	return carico;
	
}

/** Funzione che gestisce la stessa priorità tra 2 carte seguendo i criteri 
 *  del tipo di carta. Prende in ingresso 2 indici della mano di gioco.
 *  Ritorna la carta migliore da giocare tra le due ricevute in ingresso.
 */
static int gest_stessa_prior(int i1, int i2){
	D1(cout<<"INIZIO DEBUG gest_stessa_prior"<<endl);	
	/* crea una sola variabile di tipo prior_carta_gioco, in quanto in 
		gest_stessa_prior entro solo quando entrambe le carte sono dello stesso 
		tipo, quindi basta sapere il tipo di una per sapere anche quello 
		dell'altra. c1 rappresenta quindi entrambe le carte */
	prior_carta_gioco c1;
	
	// si ricorda che i1, può assumere valori 0 e 1 per come è stato impostato 
	// il programma
	if(i1==0)
		c1=carta0;
	else
		c1=carta1;

	// caso in cui entrambe le carte siano briscola piccola, e scelgo la più bassa
	if(c1 == briscola_p){  
		D2(cout<<"verificato che etrambe sono briscola piccola"<<endl);
		if(partita.player2.mano[i1].val%10 < partita.player2.mano[i2].val%10)
			return i1;
		return i2;
		
		}

	// caso in cui entrambe siano briscola alta, e scelgo la più bassa.
	// ovvero quella con valore più alto ( asso=0, tre=2, rè=9)
	if(c1 == briscola_a){
		D2(cout<<"verificato che etrambe sono briscola alta"<<endl);
		if(partita.player2.mano[i1].val%10 > partita.player2.mano[i2].val%10)
			return i1;
		return i2;
		}

	/* Il caso in cui sia liscio, punti, o carico, prende sempre quello di valore
	   minore: perchè nel liscio e punti, vuol dire che gioca la carta più 
		piccola, con minor peso mentre per il carico, gioca sì la carta minore, 
		ma equivale	all'asso, che è quella con peso maggiore, così evito di 
		verificare se strozza. */	
	D2(cout<<"verificato che sia liscio, punti, o carico"<<endl);
	if(partita.player2.mano[i1].val%10 < partita.player2.mano[i2].val%10)
		return i1;
	return i2;
	}	

/** Funzione che prende la carta con priorità più alta. Ovvero la miglior
 *  carta che il computer ha in mano. Questa funzione viene chiamata quando il 
 *  computer deve giocare per primo.
 */
static int prendi_carta_bassa(){
	D1(cout<<"INIZIO DEBUG prendi_carta_bassa"<<endl);	
	// casi in cui ci sia una carta con priorità maggiore delle altre
	if(carta0 < carta1 && carta0 < carta2)
		return 0;
	if(carta1 < carta0 && carta1 < carta2)
		return 1;
	if(carta2 < carta0 && carta2 <carta1)
		return 2;

	// rimangono i casi in cui o hanno tutte la stessa priorità 
	// o comunque 2 hanno la stessa priorità migliore e una peggiore

	// prima caso più generale: tutte e tre le carte hanno la stessa priorità
	if(carta0 == carta1 && carta0 == carta2){
		D2(cout<<"verificato che tutte le carte hanno la stessa priorità"<<endl);
		// win contiene l'indice della mano del pc con carta migliore.
		int win;

		// PROCEDO PER PASSI

		// 1--> passa le prime due carte
		win = gest_stessa_prior(0, 1);
		D2(cout<<"gestito la stessa priorità tra le prime due carte correttamente"
				<<endl);
		// 2--> passa la carta2 con la migliore delle altre due carte (win)
		if(win == carta0){
			win = gest_stessa_prior(0, 2);
			D2(cout<<"gestito la stessa priorità tra la prima e la terza carta" 
				"correttamente"<<endl);
			}
		//if obbligatorio, xk win adesso potrebbe anche essere 2
		if(win == carta1){	
			win = gest_stessa_prior(1, 2);
			D2(cout<<"gestito la stessa priorità tra le seconda e la terza carta"
				"correttamente"<<endl);
			}
		
		// 3--> sa per certo che la migliore è in win
		return win;
		}
	D2(cout<<"solo due carte hanno la stessa priorità"<<endl);
	// casi in cui solo 2 carte hanno stessa priorità
	if(carta0 == carta1){
		D2(cout<<"gestito la stessa priorità tra le prime due carte correttamente"
				<<endl);
		return gest_stessa_prior(0, 1);
		}
	if(carta0 == carta2){
		D2(cout<<"gestito la stessa priorità tra la prima e la terza carta"
				"correttamente"<<endl);		
		return gest_stessa_prior(0, 2);
		}
	// manca solo il caso in cui carta1 == carta2, evito di scrivere un if
	D2(cout<<"gestito la stessa priorità tra la seconda e la terza carta"
				"correttamente"<<endl);		
	return gest_stessa_prior(1, 2);
  	
}	


		
/** Funzione che prende la carta con priorità più alta. Molto simile alla 
 *  precedente, ma viene usata in sostituzione a 'prendi_carta_bassa' quando
 *  siamo alla fine della partita, overo quando 'partita.idx' è maggiore di 39.
 *  Funzione sempre chiamata quando il computer deve giocare per primo.
 */
static int prendi_carta_bassa_fine(){
	D1(cout<<"INIZIO DEBUG prendi_carta_bassa_fine"<<endl);	
	// casi in cui ci sia una carta con priorità maggiore delle altre
	// quando sono alla fine della partita
	
	// caso in cui carta0 = niente
	if(carta0 == niente){
		if(carta1 == niente){
			if(carta2 == niente){
				D2(cout<<"tutte tre le carte non esistono"<<endl);		
				return -1;		// tutte = niente;
				}
			else{
				D2(cout<<"solo la terza carta esiste"<<endl);	
				return 2;		// solo carta2 != niente
				}
			}
		else{				// carta1 != niente
			if(carta2 == niente){
				D2(cout<<"solo la seconda carta è diversa da niente"<<endl);	
				return 1;		// solo carta1 != niente
				}
			else{
				D2(cout<<"solo la seconda e la terza esistono"<<endl);	
				return carta1 < carta2 ? 1 : 2;		// il minore tra 1 e 2;
				}
			}
		}
	// caso in cui carta0 != niente
	else{
		if(carta1 == niente){
			if(carta2 == niente){
				D2(cout<<"solo la prima carta esiste"<<endl);	
				return 0;
				}
			else{
				D2(cout<<"solo la prima e la terza carta esistono"<<endl);	
				return carta0 < carta2 ? 0 : 2;
				}
			}
		else{
			if(carta2 == niente){
				D2(cout<<"solo la prima e la seconda carta esistono"<<endl);	
				return carta0 < carta1 ? 0 : 1;
				}
			// l' else non c'è, altrimenti non sarei alla fine della partita
			}
		}
	// rimane solo il caso in cui solo 2 carte sono diverse da niente, e hanno
	// la stessa priorità
	if(carta0 == niente){
		D2(cout<<"gestito la stessa priorità tra la seconda e la terza carta"
				"correttamente"<<endl);		
		return  gest_stessa_prior(1, 2);
		}
	if(carta1 == niente){
		D2(cout<<"gestito la stessa priorità tra la prima e la terza carta"
				"correttamente"<<endl);		
		return  gest_stessa_prior(0, 2);
		}
	D2(cout<<"gestito la stessa priorità tra la prima e la seconda carta"
				"correttamente"<<endl);		
	return  gest_stessa_prior(0, 1);
	

}	

/** Funzione che propone una carta, e il giocatore dovrà rispondere.
 *  Ovvero, il coputer gioca per primo, e deve scegliere la sua carta in base 
 *  alla mano che ha in quel momento.
 */
static int proponi_carta(){	
	D1(cout<<"INIZIO DEBUG proponi_carta"<<endl);		
																					
	/* propone una carta, e la gerarchia nella scelta è:													
	   liscio, altrimenti punticini, altrimenti briscola, altrimenti carico,
		e altrimenti briscole alte(1,3)  */

	// prende la carta i, e gli attrubuisce una determinata proprietà
	carta0=prendi_carta(0, false);
	carta1=prendi_carta(1, false);
	carta2=prendi_carta(2, false);
	D2(cout<<"recuperato le carte correttamente"<<endl);
	/* sapendo le priorità di ogni carta, prende, e quindi propone, la carta con 
	 	priorità più bassa, secondo la gerarchia detta nel commento precedente */	
	if(carta0 != niente && carta1 != niente && carta2 != niente){
		D2(cout<<"sono nel corso normale della partita: esistono tutte le carte"<<endl);
		return prendi_carta_bassa();
		}
	else{
		D2(cout<<"sono alla fine della partite: non tutte le carte esistono"<<endl);
		return prendi_carta_bassa_fine();
		}
}




//FINE PROPONI CARTA



/** Funzione che mi dice se c'è un carico, una briscola_p, una briscola_a, o 
 *  punti restituendomi true, e setta scelta al valore int corrispondente all'
 *  indice della mano con valore più piccolo
 */
static bool get_val_basso(prior_carta_gioco p, int v0, int v1, int v2){
 	D1(cout<<"INIZIO DEBUG get_val_basso"<<endl);
	// setta scelta (variabile int globale) a -1 per il controllo alla fine
	scelta=-1;

	// caso in cui tutte e tre le carte hanno priorità p
	if(carta0 == carta1 && carta0 == carta2 && carta0 == p){
		D2(cout<<"tutte e tre le carte hanno la stessa priorità"<<endl);
		// caso in cui la priorità sia 'punti' o 'briscola_p'
		if(p == punti || p == briscola_p){
			D2(cout<<"caso in cui siano punti o briscola piccola"<<endl);
			// Prende il valore più basso
			if(v0%10 < v1%10 && v0%10 < v2%10){
				D2(cout<<"la miglior carta è la prima"<<endl);
				scelta=0;
				}
			else if(v1%10 < v0%10 && v1%10 < v2%10){
				D2(cout<<"la miglior carta è la seconda"<<endl);
				scelta=1;
				}
			else{
				D2(cout<<"la miglior carta è la terza"<<endl);
				scelta=2;
				}
			}
		// caso in cui la priorità sia 'carico' o 'briscola_a'
		if(p == carico || p == briscola_a){
			D2(cout<<"caso in cui siano carico o briscola alta"<<endl);
			// prende quello con peso minore
			if(PESI[v0%10] < PESI[v1%10] && PESI[v0%10] < PESI[v2%10]){
				D2(cout<<"la miglior carta è la prima"<<endl);
				scelta=0;
				}
			else if(PESI[v1%10] < PESI[v0%10] && PESI[v1%10] < PESI[v2%10]){
				D2(cout<<"la miglior carta è la seconda"<<endl);
				scelta=1;
				}
			else{
				D2(cout<<"la miglior carta è la seconda"<<endl);
				scelta=2;
				}
			}
		}
	
	// se scelta è diversa da -1, ritorna true, perchè ha già la scelta migliore
	if(scelta != -1)
		return true;
	D2(cout<<"solo due carte hanno la stessa priorità"<<endl);
	// da qui al più ci sono due carte con stessa priorità di p

	// se la carta0 ha la stasse priorità del parametro p passato alla funzione
	if(carta0 == p)
		scelta=0;		//0 corrisponde all'indice della mano (infatti carta0)
		

	// se la carta1 ha stessa priorità di p
	if(carta1 == p){
		D2(cout<<"la seconda carta ha la priorità p"<<endl);
		// caso in cui contemporaneamente anche carta0 ha stessa priorità
		if(carta0 == p){
			D2(cout<<"la prima e la seconda carta hanno la stessa priorità"<<endl);
			// caso in cui la priorità sia 'punti' o 'briscola_p'
			if(p == punti || p == briscola_p){
				D2(cout<<"caso in cui siano punti o briscola piccola"<<endl);
				// prende il valore più basso
				if(v0%10 < v1%10){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				}
			// caso in cui la priorità sia 'carico' o 'briscola_a'
			if(p == carico || p == briscola_a){
				D2(cout<<"caso in cui siano carico o briscola alta"<<endl);
				// prende quello con peso minore
				if(PESI[v0%10] < PESI[v1%10]){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				}
			}
		// carta0 non ha la stessa priorità
		else{
			scelta=1;
			D2(cout<<"la miglior carta è la seconda, solo lei ha priorità p"<<endl);
			}
		}

	// se carta2 ha stessa priorità di p			
	if(carta2 == p){
		D2(cout<<"la terza carta ha la priorità p"<<endl);
		//  caso in cui contemporaneamente anche carta0 ha stessa priorità
		if(carta0 == p){
			D2(cout<<"la prima e la terza carta hanno la stessa priorità"<<endl);
			// caso in cui la priorità sia 'punti' o 'briscola_p'
			if(p == punti || p == briscola_p){
				D2(cout<<"caso in cui siano punti o briscola piccola"<<endl);
				// prende il valore più basso
				if(v0%10 < v2%10){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			// caso in cui la priorità sia 'carico' o 'briscola_a'
			if(p == carico || p == briscola_a){
				D2(cout<<"caso in cui siano carico o briscola alta"<<endl);
				// prende quello con peso minore
				if(PESI[v0%10] < PESI[v2%10]){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			}

		// caso in cui contemporaneamente anche carta1 ha stessa priorità
		// ma non anche carta0
		else if(carta1 == p){
			D2(cout<<"la seconda e la terza carta hanno la stessa priorità"<<endl);
			// caso in cui la priorità sia 'punti' o 'briscola_p'
			if(p == punti || p == briscola_p){
				D2(cout<<"caso in cui siano punti o briscola piccola"<<endl);
				// prende il valore più basso
				if(v1%10 < v2%10){
					D2(cout<<"la miglior carta è la seconda"<<endl);
					scelta=1;
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			// caso in cui la priorità sia 'carico' o 'briscola_a'
			if(p == carico || p == briscola_a){
				D2(cout<<"caso in cui siano carico o briscola alta"<<endl);
				// prende quello con peso minore
				if(PESI[v1%10] < PESI[v2%10]){
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			}
		// solo carta2 ha la 
		else{
			scelta=2;
			D2(cout<<"la miglior carta è la terza, solo lei ha priorità p"<<endl);
			}
		}
	
	if(scelta != -1)
		return true;
	D2(cout<<"nessuna carta ha priorità p"<<endl);
	return false;
} 


/** Funzione che restituisce true se c'è un carico o punti e setta scelta al 
 *  valore int corrispondente all'indice della mano con valore più alto
 */
static bool get_val_alto(prior_carta_gioco p, int v0, int v1, int v2, int va){
 	D1(cout<<"INIZIO DEBUG get_val_alto"<<endl);
	// setta scelta (variabile int globale) a -1 per il controllo alla fine
	scelta=-1;

	// caso in cui tutte e tre le carte hanno priorità p
	if(carta0 == carta1 && carta0 == carta2 && carta0 == p && (v0/10) == (va/10) ){
		D2(cout<<"tutte e tre le carte hanno la stessa priorità e sono dello stesso"
			"seme della carta dell'avversario"<<endl);
		// caso in cui la priorità sia 'punti' o 'briscola_p'
		if(p == punti){
			D2(cout<<"caso in cui siano punti"<<endl);
			// Prende il valore più basso
			if(v0%10 > v1%10 && v0%10 > v2%10){
				scelta=0;
				D2(cout<<"la miglior carta è la prima"<<endl);
				}
			else if(v1%10 > v0%10 && v1%10 > v2%10){
				scelta=1;
				D2(cout<<"la miglior carta è la seconda"<<endl);
				}
			else{
				scelta=2;
				D2(cout<<"la miglior carta è la terza"<<endl);
				}
			}
		// caso in cui la priorità sia 'carico' o 'briscola_a'
		if(p == carico){
			D2(cout<<"caso in cui siano carico"<<endl);
			// prende quello con peso minore
			if(PESI[v0%10] > PESI[v1%10] && PESI[v0%10] > PESI[v2%10]){
				scelta=0;
				D2(cout<<"la miglior carta è la prima"<<endl);
				}
			else if(PESI[v1%10] > PESI[v0%10] && PESI[v1%10] > PESI[v2%10]){
				scelta=1;
				D2(cout<<"la miglior carta è la seconda"<<endl);
				}
			else{
				scelta=2;
				D2(cout<<"la miglior carta è la terza"<<endl);
				}
			}
		}
	
	// se scelta è diversa da -1, ritorna true, perchè ha già la scelta migliore
	if(scelta != -1)
		return true;

	// da qui al più ci sono due carte con stessa priorità di p

	// se la carta0 ha la stasse priorità del parametro p passato alla funzione
	if(carta0 == p && ((v0/10) == (va/10)))
		scelta=0;		//0 corrisponde all'indice della mano (infatti carta0)

	// se la carta1 ha stessa priorità di p
	if(carta1 == p && ((v1/10) == (va/10))){
		D2(cout<<"la seconda carta ha la priorità p"<<endl);
		// caso in cui contemporaneamente anche carta0 ha stessa priorità
		if(carta0 == p && ((v0/10) == (va/10))){
			D2(cout<<"la prima e la seconda carta hanno la stessa priorità "<<endl);
			// caso in cui la priorità sia 'punti' o 'briscola_p'
			if(p == punti){
				D2(cout<<"caso in cui siano punti"<<endl);
				// prende il valore più basso
				if(v0%10 > v1%10){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				}
			// caso in cui la priorità sia 'carico' o 'briscola_a'
			if(p == carico){
				D2(cout<<"caso in cui siano carico"<<endl);
				// prende quello con peso minore
				if(PESI[v0%10] > PESI[v1%10]){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				}
			}
		// carta0 non ha la stessa priorità
		else
			scelta=1;
		}

	// se carta2 ha stessa priorità di p			
	if(carta2 == p && ((v2/10) == (va/10))){
		D2(cout<<"la terza carta ha la priorità p"<<endl);
		//  caso in cui contemporaneamente anche carta0 ha stessa priorità
		if(carta0 == p && ((v0/10) == (va/10))){
			D2(cout<<"la prima e la terza carta hanno la stessa priorità "<<endl);
			// caso in cui la priorità sia 'punti' o 'briscola_p'
			if(p == punti){
				D2(cout<<"caso in cui siano punti"<<endl);
				// prende il valore più basso
				if(v0%10 > v2%10){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			// caso in cui la priorità sia 'carico' o 'briscola_a'
			if(p == carico){
				D2(cout<<"caso in cui siano carico"<<endl);
				// prende quello con peso minore
				if(PESI[v0%10] > PESI[v2%10]){
					scelta=0;
					D2(cout<<"la miglior carta è la prima"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			}

		// caso in cui contemporaneamente anche carta1 ha stessa priorità
		// ma non anche carta0
		else if(carta1 == p && ((v1/10) == (va/10))){
			D2(cout<<"la seconda e la terza carta hanno la stessa priorità "<<endl);
			// caso in cui la priorità sia 'punti' o 'briscola_p'
			if(p == punti){
				D2(cout<<"caso in cui siano punti"<<endl);
				// prende il valore più basso
				if(v1%10 > v2%10){
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			// caso in cui la priorità sia 'carico' o 'briscola_a'
			if(p == carico){
				D2(cout<<"caso in cui siano carico"<<endl);
				// prende quello con peso minore
				if(PESI[v1%10] > PESI[v2%10]){
					scelta=1;
					D2(cout<<"la miglior carta è la seconda"<<endl);
					}
				else{
					scelta=2;
					D2(cout<<"la miglior carta è la terza"<<endl);
					}
				}
			}
		// solo carta2 ha la 
		else{
			scelta=2;
			D2(cout<<"la miglior carta è la terza, solo lei ha priorità p"<<endl);
			}
		}
	
	if(scelta != -1)
		return true;
	return false;
} 




/** Funzione che seglie di fatto la carta migliore da giocare per rispondere
 *	 all'avversario. quindi questa funzione la chiama quando il computer gioca 
 *  per secondo.
 */
static int prendi_carta_bassa2(int idx, prior_carta_gioco avv){
	D1(cout<<"INIZIO DEBUG prendi_carta_bassa2"<<endl);
	// Indice per il mio switch.
	int n;
        
	if(avv == liscio)
		n=0;
	else if(avv == punti)
		n=1;
	else if(avv == briscola_p)
		n=2;
	else if(avv == carico)
		n=3;
	else
		n=4;
	
	// contengono i valori int delle carte della mano del computer
	int val_c0, val_c1, val_c2;
	val_c0=partita.player2.mano[0].val;
	val_c1=partita.player2.mano[1].val;
	val_c2=partita.player2.mano[2].val;

	// contiene il valore int della carta giocata dal giocatore.
	int val_avv;
	val_avv=partita.player1.mano[idx].val;

	switch(n){
		
	  //caso in cui sia liscio
	  case 0:
				D1(cout<<"IL GIOCATORE HA GIOCATO LISCIO"<<endl);
				// andiamo per passi...

				// 1--> cerca di strozzare 
				if(get_val_alto(carico, val_c0, val_c1, val_c2, val_avv)==true){
					D2(cout<<"il computer è riuscito a strozzare con il carico più"
								" alto"<<endl);
					return scelta;
					}
				
				// 2--> cerca di andare liscio

				/* per semplicità, gioca un liscio di seme diverso da quello della 
				 	carta giocata dal giocatore       */
				if(carta0 == liscio && val_c0/10 != val_avv/10)
					return 0;
				if(carta1 == liscio && val_c1/10 != val_avv/10)
					return 1;
				if(carta2 == liscio && val_c2/10 != val_avv/10)
					return 2;
				// dopodichè altrimenti gioca liscio stesso seme.
				if(carta0 == liscio && val_c0 < val_avv)
					return 0;
				if(carta1 == liscio && val_c1 < val_avv)
					return 1;
				if(carta2 == liscio && val_c2 < val_avv)
					return 2;
				D2(cout<<"il computer non è riuscito ad andare liscio senza prendere" 
							" la mano"<<endl);

				// 3--> cerca di giocare punti dello stesso seme per vincere la mano
				// valore più alto
				if(get_val_alto(punti, val_c0, val_c1, val_c2, val_avv)==true){
					D2(cout<<"il computer è riuscito a strozzare con dei punti"<<endl);
					return scelta;
					}
	
				// 4--> cerca di prendere con liscio

				// naturalmente saranno lisci dello stesso seme della carta avversario
				// gli altri li avrei già esclusi
				if(carta0 == liscio)
					return 0;
				if(carta1 == liscio)
					return 1;
				if(carta2 == liscio)
					return 2;
				D2(cout<<"il computer non è riuscito a prendere con un liscio"<<endl);

				// 5--> cerca di perdere meno punti possibile
				if(get_val_basso(punti, val_c0, val_c1, val_c2)==true){
					D2(cout<<"il computer è riuscito a perdere meno punti possibile"<<endl);
					return scelta;
					}

				// 6--> cerca di prendere con la briscola piccola, valore più basso
				if(get_val_basso(briscola_p, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola piccola"
								" più bassa"<<endl);
					return scelta;
					}
	 			
				// 7--> cerca di prendere con la briscola alta, ma valore più basso
				if(get_val_basso(briscola_a, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola alta"
								" più bassa"<<endl);
					return scelta;
					}
	
				// 8--> cerca di cedere carico, valore più basso
				if(get_val_basso(carico, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere con il carico"
								" più basso"<<endl);
					return scelta;
					}

				//NON DOVREI MAI ARRIVARE FINO A QUI
				cout<<"ERRORE MANCA CASO!!! IN CASE0"<<endl;
				break;	
	
	  //caso in cui sia punti
	  case 1: 
				D1(cout<<"IL GIOCATORE HA GIOCATO PUNTI"<<endl);
				// andiamo per passi...

				// 1--> cerca di strozzare 
				if(get_val_alto(carico, val_c0, val_c1, val_c2, val_avv)==true){
					D2(cout<<"il computer è riuscito a strozzare con il carico più "
								"alto"<<endl);
					return scelta;
					}
				
				// 2--> cerca di giocare liscio
				if(carta0 == liscio)
					return 0;
				if(carta1 == liscio)
					return 1;
				if(carta2 == liscio)
					return 2;
				D2(cout<<"il computer non è riuscito ad andare liscio"<<endl);

				// 3--> cerca di prendere con punti, i più possibili
				if(get_val_alto(punti, val_c0, val_c1, val_c2, val_avv)==true){
					D2(cout<<"il computer è riuscito a prendere con punti stesso seme"
								" più alto"<<endl);
					return scelta;
					}
	
				// 4--> cerca di prendere con briscola piccola, valore più basso
				if(get_val_basso(briscola_p, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola piccola"
								" più bassa"<<endl);
					return scelta;
					}
	
				// 5--> cerca di cedere meno punti possibile
				if(get_val_basso(punti, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere i punti minori"<<endl);
					return scelta;
					}

				// 6--> cerca di prendere con briscola alta, ma valore più basso
				if(get_val_basso(briscola_a, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola alta"
								" più bassa"<<endl);
					return scelta;
					}

				// 7--> cerca di cedere carico, valore più basso
				if(get_val_basso(carico, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere il carico più "
								"basso"<<endl);
					return scelta;
					}

				//NON DOVREI MAI ARRIVARE FINO A QUI
				cout<<"ERRORE MANCA CASO!!! IN CASE1"<<endl;
				break;
	
	  // Caso in cui sia briscola_p.
	  case 2:
				D1(cout<<"IL GIOCATORE HA GIOCATO BRISCOLA PICCOLA"<<endl);
				// andiamo per passi...
		
				// 1--> cerca di giocare liscio, qualsiasi esso sia
				if(carta0 == liscio)
					return 0;
				if(carta1 == liscio)
					return 1;
				if(carta2 == liscio)
					return 2;	
				D2(cout<<"il computer non è riuscito ad andare liscio"<<endl);

				// 2--> cerca di cedere meno punti possibili
				if(get_val_basso(punti, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere meno punti possibile"<<endl);
					return scelta;
					}
				
				// 3--> cerca di giocare briscola piccola più bassa
				if(get_val_basso(briscola_p, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere/prendere con la "
								"briscola piccola più bassa"<<endl);
					return scelta; 
					}

				// 4--> cerca di prendere con briscola alta
				if(get_val_basso(briscola_a, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola"
								" alta più bassa"<<endl);
					return scelta;
					}

				// 5--> cede e gioca carico
				if(get_val_basso(carico, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere il carico più "
								"basso"<<endl);
					return scelta;
					}
	
				//NON DOVREI MAI ARRIVARE FINO A QUI
				cout<<"ERRORE MANCA CASO!!! IN CASE2"<<endl;
				break;

	  // caso in cui sia carico
	  case 3: 
				D1(cout<<"IL GIOCATORE HA GIOCATO CARICO"<<endl);
				// andiamo per passi...

				// 1--> gaurda se ha l'asso per strozzare sul tre, e lo gioca				
				if(val_avv%10 == 2){		// se l'avversario ha giocato un tre
					if((carta0 == carico) && (val_c0%10 == 0) && (val_c0/4 == 
								val_avv/4))
						return 0;
					if((carta1 == carico) && (val_c1%10 == 0) && (val_c1/4 == 	
								val_avv/4))
						return 1;
					if((carta2 == carico) && (val_c2%10 == 0) && (val_c2/4 == 
								val_avv/4))
						return 2;
					D2(cout<<"il computer non è riuscito a strozzare con l'asso"<<endl);
					}
				
				// 2--> cerca di prendere con briscola piccola
				if(get_val_basso(briscola_p, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola"
								" bassa più bassa"<<endl);
					return scelta;
					}

				// 3--> cerca di prendere con briscola alta
				if(get_val_basso(briscola_a, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola"
								" alta più bassa"<<endl);
					return scelta;
					}

				// 4--> cerca di giocare liscio
				if(carta0 == liscio)
					return 0;
				if(carta1 == liscio)
					return 1;
				if(carta2 == liscio)
					return 2;
				D2(cout<<"il computer non è riuscito ad andare liscio"<<endl);

				// 5--> cerca di cededere meno punti possibili
				if(get_val_basso(punti, val_c0, val_c1, val_c2) == true){
						D2(cout<<"il computer è riuscito a cedere meno punti possibile"
								<<endl);
					return scelta;
					}

				// 6--> cerca di perdere il carico più piccolo										
				if(get_val_basso(carico, val_c0, val_c1, val_c2) == true){
						D2(cout<<"il computer è riuscito a cedereil carico più basso"
								<<endl);
					return scelta;
					}

				//NON DOVREI MAI ARRIVARE FINO A QUI
				cout<<"ERRORE MANCA CASO!!! IN CASE3"<<endl;
				break;

	  // caso in cui sia briscola alta
	  case 4: 
				D1(cout<<"IL GIOCATORE HA GIOCATO BRISCOLA ALTA"<<endl);
				// andiamo per passi...

				// 1--> gaurda se ha l'asso per strozzare sul tre, e lo gioca
				if(val_avv%10 == 2){				// se l'avversario ha giocato un tre
					if((carta0 == briscola_a) && (val_c0%10 == 0))
						return 0;
					if((carta1 == briscola_a) && (val_c1%10 == 0))
						return 1;
					if((carta2 == briscola_a) && (val_c2%10 == 0))
						return 2;
					D2(cout<<"il computer non è riuscito a strozzare con l'asso"<<endl);
					}	

				// 2--> cerca di giocare liscio
				if(carta0 == liscio)
					return 0;
				if(carta1 == liscio)
					return 1;
				if(carta2 == liscio)
					return 2;
				D2(cout<<"il computer non è riuscito ad andare liscio"<<endl);

				// 3--> cerca di cedere meno punti possibile
				if(get_val_basso(punti, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a cedere meno punti possibile"
								<<endl);
					return scelta;
					}

				// 4--> cerca di perdere briscola piccola, che vale meno
				if(get_val_basso(briscola_p, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a perdere la briscola bassa più "
								"bassa"<<endl);
					return scelta;
					}

				// 5--> cerca di cedere il carico più basso
				if(get_val_basso(carico, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a cedere il carico più basso"<<endl);
					return scelta;
					}

				// 6--> cerca di cedere briscola alta
				if(get_val_basso(briscola_a, val_c0, val_c1, val_c2) == true){
					D2(cout<<"il computer è riuscito a prendere con la briscola"
								" alta più bassa"<<endl);
					return scelta;
					}

				//NON DOVREI MAI ARRIVARE FINO A QUI
				cout<<"ERRORE MANCA CASO!!! IN CASE3"<<endl;
				break;

		 //caso impossibile
	 	 default : cout<<"ERRORE, IMPOSSIBILE\n";
		}
	
	cout<<"IMPOSSIBILE!! MAI ARRIVARE QUI!!\n";
	return -1;
}

/** Funzione che risponde alla carta giocata. Ovvero, funzione per scegliere
 *  la carta in base a quella che ha giocato player1. Questa funzione si appoggia
 *  alla funzione 'prendi_carta_bassa2' per la scelta vera e propria della carta.
 */
static int rispondi_carta(){
	D1(cout<<"INIZIO DEBUG rispondi_carta"<<endl);
	// recupera la carta giocata dall'avversario.
	int val_c_pr1;
	val_c_pr1=ricerca_id_carta(true); //true per la carta player1
	D2(cout<<"recuperata la carta del giocatore con successo"<<endl);

	// da una priorità alla carta giocata dall'avversario
	prior_carta_gioco carta_plr1;
	carta_plr1=prendi_carta(val_c_pr1, true);
	D2(cout<<"attribuito una priorità alla carta del giocatore con successo"<<endl);

	// recupera le tre carte della mano del computer
	carta0 = prendi_carta(0, false);
	D2(cout<<"attribuito una proprietà alla prima carta del computer"<<endl);
	carta1 = prendi_carta(1, false);
	D2(cout<<"attribuito una proprietà alla seconda carta del computer"<<endl);	
	carta2 = prendi_carta(2, false);
	D2(cout<<"attribuito una proprietà alla terza carta del computer"<<endl);
	
	// trova la carta migliore da giocare
	int vinc;
	vinc = prendi_carta_bassa2(val_c_pr1, carta_plr1);
	D2(cout<<"trovato la carta migliore da giocare"<<endl);
	
	return vinc;
}

/** Funzione che sceglie di fatto la carta del pc da giocare.
 *  Ho due possibili casi : 
 *  1 --> il pc gioca per primo, quindi turno=primo;
 *  2 --> il pc gioca per secondo, quindi turno=secondo;
 *  Ritorna l'indice della player2.mano corrispondente alla carte da giocare.
 */
static int scelta_carta(){
	D1(cout<<"INIZIO DEBUG scelta_carta"<<endl);
	// indice corrispondente alla carta della mano del pc che deve giocare
	int i;
	if(turno == primo){
		i=proponi_carta();
		D2(cout<<"proposto carta con successo"<<endl);
		}
		
	else{
		i=rispondi_carta();
		D2(cout<<"risposto carta con successo"<<endl);
		}
	partita.player2.mano[i].selez=true;
	return i;
}

/** Funzione che gestisce le ultime mano della partita, quando il computer non 
 *  ha più 3 carte in mano, ma gliene rimangono una o due.
 */
static void gestione_fine_partita(){
	D1(cout<<"INIZIO DEBUG gestione_fine_partita"<<endl);
	if(partita.player2.mano[0].esiste == false)
		carta0=niente;
	if(partita.player2.mano[1].esiste == false)
		carta1=niente;
	if(partita.player2.mano[2].esiste == false)
		carta2=niente;
	D1(cout<<"FINE DEBUG GESTIONE FINE PARTITA"<<endl);
}

/** Funzione che permette di far giocare il Computer.
 */
static void gioca_pc(){
	D1(cout<<"INIZIO DEBUG gioca_pc"<<endl);
	gestione_fine_partita();
	D2(cout<<"gestione fine partita con successo"<<endl);
	int i=scelta_carta();
	
	ostringstream oss;
	oss<<i+3;

	//mentre setto la carta "premuta" dal pc a false
	gtk_widget_set_visible(GTK_WIDGET(gtk_builder_get_object
							(builder,oss.str().c_str())),false);
	oss.clear();
	D1(cout<<"FINE DEBUG GIOCA PC"<<endl);
}

/** Funzione che gestisce il turno del computer. 
 *  Ovvero gioca, imposta le carte sul tavolo, e cambia giocatore.
 */
void gioca_mano_pc(){
	D1(cout<<"INIZIO DEBUG gioca_mano_pc"<<endl);
	gioca_pc();
	D2(cout<<"il computer ha giocato con successo"<<endl);
	setta_immagine_tavolo();
	D2(cout<<"settato le immagini del tavolo con successo"<<endl);
	gioca=giocatore;	
	D1(cout<<"FINE DEBUG GIOCA MANO PC"<<endl);
}
